// 1.插件：挂载$store
// 2.实现Store

let Vue

class Store {
    constructor(options) {
        // data响应式处理
        // this.$store.state.xx

        
        this._mutations = options.mutations
        this._actions = options.actions
        this._getters = options.getters

        // 定义computed选项
        const computed = {}
        this.getters = {}
        const store = this
        console.log(store)
        Object.keys(this._getters).forEach(key => {
            // 获取用户定义得getter
            const fn = store._getters[key]
            // 转换为computed可以使用无参数形式
            computed[key] = function(){
                return fn(store.state)
            }
            // 为getters定义只读属性
            Object.defineProperty(store.getters,key,{
                get:()=>store._vm[key]
            })
        })

        this._vm = new Vue({
            data() {
                return {
                    // 加上$，不让Vue做代理
                    $$state: options.state
                }
            },
            computed
        })
        // this._vm = new Vue({
        //     data: {
        //         $$state: options.state
        //     }
        // })

        // 修改this指向
        this.commit = this.commit.bind(this)
        this.dispatch = this.dispatch.bind(this)
        // this.getters = this.getters.bind(this)
        // defineProperty(this.getters, 'doubleCounter', {get(){}})
        // 最后还能利用vue计算属性做缓存
    }
    get state() {
        // console.log(this._vm)
        return this._vm._data.$$state
    }
    set state(v) {
        // console.log(v)
        console.log("不能直接覆盖state，你可以使用replaceState");
    }
    // commit('add',10)
    commit(type, payload) {
        // this.$$
        // console.log(type, payload);
        const mutation = this._mutations[type]
        if (!mutation) {
            console.log("错误的muitation名称！")
            return
        }
        mutation(this, payload)
    }
    dispatch(type, payload) {
        // console.log(type, payload);
        const action = this._actions[type] 
        // console.log(action)
        if (!action) {
            console.error("错误的action名称！")
            return
        }
        action(this, payload)
    }
    getters(type){
        const getter = this._getters[type]
        if(!getter){
            console.error("错误的getter名称！")
            return
        }
        getter(this)
    }
}

function install(_Vue) {
    Vue = _Vue
    // 注册 $store
    Vue.mixin({
        beforeCreate() {
            if (this.$options.store) {
                console.log("我是根实例")
                Vue.prototype.$store = this.$options.store
            }
        },
    })
}
export default { Store, install }